<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Sales\Event;

use Doctrine\ORM\EntityManager;
use Goods\Entity\GoodsStock;
use Goods\Service\GoodsInSpecGoodsManager;
use Goods\Service\GoodsSalesRecordManager;
use Goods\Service\GoodsStockManager;
use Laminas\EventManager\Event;
use Laminas\EventManager\EventManagerInterface;
use Laminas\EventManager\ListenerAggregateInterface;
use Laminas\I18n\Translator\Translator;
use Sales\Entity\OrderDiscountRecord;
use Shop\Service\ShopUserManager;
use User\Entity\User;
use User\Entity\UserIntegralConfirm;
use User\Service\IntegralLogManager;
use User\Service\UserIntegralConfirmManager;

class SalesListener implements ListenerAggregateInterface
{
    protected $listeners = [];

    private $entityManager;
    private $translator;
    private $goodsStockManager;
    private $goodsInSpecGoodsManager;
    private $goodsSalesRecordManager;
    private $shopUserManager;
    private $integralLogManager;
    private $userIntegralConfirmManager;

    public function __construct(
        EntityManager           $entityManager,
        GoodsStockManager       $goodsStockManager,
        GoodsInSpecGoodsManager $goodsInSpecGoodsManager,
        GoodsSalesRecordManager $goodsSalesRecordManager,
        ShopUserManager         $shopUserManager,
        IntegralLogManager      $integralLogManager,
        UserIntegralConfirmManager $userIntegralConfirmManager
    )
    {
        $this->entityManager        = $entityManager;
        $this->translator           = new Translator();
        $this->goodsStockManager    = $goodsStockManager;
        $this->goodsInSpecGoodsManager  = $goodsInSpecGoodsManager;
        $this->goodsSalesRecordManager  = $goodsSalesRecordManager;
        $this->shopUserManager      = $shopUserManager;
        $this->integralLogManager   = $integralLogManager;
        $this->userIntegralConfirmManager   = $userIntegralConfirmManager;
    }

    public function attach(EventManagerInterface $events, $priority = 1)
    {
        $shareEvents = $events->getSharedManager();

        //前台取消订单时，订单中的商品购买数量返回库存（如果商品设置有货，则不返回），销量修改
        $this->listeners[] = $shareEvents->attach(
            'Shop\Controller\HomeOrderController', 'shop.order.cancel.post', [$this, 'onShopGoodsReturnStock']
        );
        //前台取消订单时，订单中的抵扣进行返回处理（积分返回，优惠券等不返回）
        $this->listeners[] = $shareEvents->attach(
            'Shop\Controller\HomeOrderController', 'shop.order.cancel.post', [$this, 'onShopOrderDiscountReturn']
        );
        //后台取消订单时，订单中的商品购买数量返回库存（如果商品设置有货，则不返回），销量修改
        $this->listeners[] = $shareEvents->attach(
            'Sales\Controller\IndexController', 'backstage-order.cancel.post', [$this, 'onShopGoodsReturnStock']
        );
        //后台取消订单时，订单中的抵扣进行返回处理（积分返回，优惠券等不返回）
        $this->listeners[] = $shareEvents->attach(
            'Sales\Controller\IndexController', 'backstage-order.cancel.post', [$this, 'onShopOrderDiscountReturn']
        );

        //前台确认订单时，如存在获取积分则进行积分处理
        $this->listeners[] = $shareEvents->attach(
            'Shop\Controller\HomeOrderController', 'shop.order.receipt.post', [$this, 'onUserIntegralConfirmChange'], 99
        );
        //后台确认订单时，如存在获取积分则进行积分处理
        $this->listeners[] = $shareEvents->attach(
            'Sales\Controller\IndexController', 'backstage-order.receipt.post', [$this, 'onUserIntegralConfirmChange'], 99
        );
    }

    public function detach(EventManagerInterface $events)
    {
        foreach ($this->listeners as $index => $listener) {
            $events->detach($listener);
            unset($this->listeners[$index]);
        }
    }

    /**
     * 取消订单时，订单中的商品购买数量返回库存（如果商品设置有货，则不返回），销量修改
     * @param Event $event
     */
    public function onShopGoodsReturnStock(Event $event)
    {
        $orderInfo = $event->getParam('orderInfo');
        foreach ($orderInfo->getOrderGoods() as $goodsValue) {
            $goodsStock = $this->entityManager->getRepository(GoodsStock::class)->findOneBy(['goodsId' => $goodsValue->getGoodsId()]);
            if($goodsStock && $goodsStock->getStockShowState() == 0) {
                if($goodsValue->getInSpecGoodsId() > 0) {
                    $this->goodsInSpecGoodsManager->editInSpecGoodsStock($goodsValue->getBuyNum(), '+', $goodsValue->getInSpecGoodsId(), $goodsValue->getGoodsId());
                } else {
                    $this->goodsStockManager->changeGoodsStockNum($goodsValue->getBuyNum(), '+', $goodsValue->getGoodsId());
                }
            }
            //销量修改，减少
            $this->goodsSalesRecordManager->changeGoodsSalesNum($goodsValue->getBuyNum(), '-', $goodsValue->getGoodsId());
        }
    }

    public function onShopOrderDiscountReturn(Event $event)
    {
        $orderInfo = $event->getParam('orderInfo');
        $orderDiscountList = $this->entityManager->getRepository(OrderDiscountRecord::class)->findBy(['orderId' => $orderInfo->getOrderId()]);
        if ($orderDiscountList) foreach ($orderDiscountList as $discountValue) {
            if ($discountValue->getDiscountType() == 'integral') {//积分
                $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userId' => $orderInfo->getUserId()]);
                $integralType1Num = $userInfo->getIntegralType1Num() + $discountValue->getId();
                $this->shopUserManager->updateUserUserIntegral(['integralType1Num' => $integralType1Num], $orderInfo->getUserId());
                $logArray = [
                    'userId'            => $orderInfo->getUserId(),
                    'userName'          => $orderInfo->getUserName(),
                    'integralLogInfo'   => $this->translator->translate('订单取消，积分购买退回').' '.$discountValue->getId().' '.$this->translator->translate('订单编号').$orderInfo->getOrderSn(),
                    'changeIntegralNum' => $discountValue->getId(),
                    'integralNum'       => $integralType1Num,
                    'integralTypeId'    => 1,
                    'integralLogTime'   => time(),
                    'adminId'           => 0
                ];
                //当是管理员操作时，进行记录
                if ($event->getParam('admin_id') > 0) {
                    $logArray['adminId']    = $event->getParam('admin_id');
                    $logArray['adminName']  = $event->getParam('admin_name');
                }
                $this->integralLogManager->addIntegralLog($logArray);
            }
        }
    }

    /**
     * 确认订单时，如存在获取积分则进行积分处理
     * @param Event $event
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function onUserIntegralConfirmChange(Event $event)
    {
        $orderInfo = $event->getParam('orderInfo');
        $integralConfirm = $this->entityManager->getRepository(UserIntegralConfirm::class)->findOneBy(['userId' => $orderInfo->getUserId(), 'id' => $orderInfo->getOrderId(), 'confirmType' => 'order', 'confirmState' => 0]);
        if(!empty($integralConfirm)) {
            $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userId' => $orderInfo->getUserId()]);

            $updateIntegralArray = [];
            if($integralConfirm->getIntegralType1Num() > 0) $updateIntegralArray['integralType1Num'] = $userInfo->getIntegralType1Num() + $integralConfirm->getIntegralType1Num();
            if($integralConfirm->getIntegralType2Num() > 0) $updateIntegralArray['integralType2Num'] = $userInfo->getIntegralType2Num() + $integralConfirm->getIntegralType2Num();
            if($this->shopUserManager->updateUserUserIntegral($updateIntegralArray, $orderInfo->getUserId())) {
                if($integralConfirm->getIntegralType1Num() > 0) {
                    $this->integralLogManager->addIntegralLog([
                        'userId'            => $userInfo->getUserId(),
                        'userName'          => $userInfo->getUserName(),
                        'integralLogInfo'   => $this->translator->translate('购物').'+'.$integralConfirm->getIntegralType1Num().' '.$this->translator->translate('订单编号').$orderInfo->getOrderSn(),
                        'changeIntegralNum' => $integralConfirm->getIntegralType1Num(),
                        'integralNum'       => $updateIntegralArray['integralType1Num'],
                        'integralTypeId'    => 1,
                        'integralLogTime'   => time(),
                        'adminId'           => 0
                    ]);
                }
                if($integralConfirm->getIntegralType2Num() > 0) {
                    $this->integralLogManager->addIntegralLog([
                        'userId'            => $userInfo->getUserId(),
                        'userName'          => $userInfo->getUserName(),
                        'integralLogInfo'   => $this->translator->translate('购物').'+'.$integralConfirm->getIntegralType2Num().' '.$this->translator->translate('订单编号').$orderInfo->getOrderSn(),
                        'changeIntegralNum' => $integralConfirm->getIntegralType2Num(),
                        'integralNum'       => $updateIntegralArray['integralType2Num'],
                        'integralTypeId'    => 2,
                        'integralLogTime'   => time(),
                        'adminId'           => 0
                    ]);
                }
            }
            $this->userIntegralConfirmManager->editUserIntegralConfirm(['confirmState' => 1, 'confirmTime' => time()], $integralConfirm);
        }
    }
}